import Vue from 'vue';
import { create, all } from 'mathjs';
import { dayjs } from '@/main.js';
export function useVModel(obj, emit = 'input') {
	let _this = this;
	obj ??= _this.value;
	if (typeof obj !== 'object') {
		return obj;
	}
	return new Proxy(obj, {
		get(target, propKey, receiver) {
			return Reflect.get(target, propKey, receiver);
		},
		set(target, propKey, value, receiver) {
			_this.$emit(emit, { ...target, [propKey]: value });
			return Reflect.set(target, propKey, value, receiver);
		},
	});
}

export function A_formatTime(time, reg = 0) {
	if (!time || time == 0 || time == '0') return '';
	switch (reg) {
		case 0:
			reg = 'YYYY-MM-DD';
			break;
		case 1:
			reg = 'YYYY-MM-DD HH:mm:ss';
			break;
	}
	let pass = dayjs(time)?.isValid?.();
	if (!pass) return time;

	return dayjs(time).format(reg);
}

export function refRedirect(ref) {
	for (const key in this.$refs[ref]) {
		if (Object.hasOwnProperty.call(this.$refs[ref], key)) {
			let element = this.$refs[ref][key];
			let reg = /(\_|\$)/g;
			if (
				!reg.test(key) &&
				Object.prototype.toString.call(element) === '[object Function]'
			) {
				this[`${ref}_${key}`] = element;
			}
		}
	}
}
export function notEmpty(value) {
	let result = true;
	if (value === undefined || value === null || value === '') {
		result = false;
	} else {
		result = true;
	}
	if (Object.prototype.toString.call(value) === '[object Array]') {
		if (value.length == 0) {
			result = false;
		} else {
			result = true;
		}
	}
	if (Object.prototype.toString.call(value) === '[object Object]') {
		if (Object.keys(value).length == 0) {
			result = false;
		} else {
			result = true;
		}
	}
	return result;
}
export function Empty(value) {
	let result = true;
	if (value === undefined || value === null || value === '') {
		result = true;
	} else {
		result = false;
	}
	if (Object.prototype.toString.call(value) === '[object Array]') {
		if (value.length == 0) {
			result = true;
		} else {
			result = false;
		}
	}
	if (Object.prototype.toString.call(value) === '[object Object]') {
		if (Object.keys(value).length == 0) {
			result = true;
		} else {
			result = false;
		}
	}
	return result;
}
export function scrollToError(ref) {
	let error = ref ?? document.querySelector('.el-form-item.is-error');
	let parentNodeClass = error?.parentElement?.className;
	let options = {
		behavior: 'smooth',
		block: 'center',
		inline: 'center',
	};
	if (parentNodeClass === 'cell') {
		options.behavior = 'auto';
	}
	error?.scrollIntoView(options);
}
const config = {
	epsilon: 1e-12,
	matrix: 'Matrix',
	number: 'number',
	precision: 64,
	predictable: false,
	randomSeed: null,
};
const math = create(all, config);

//开方
export function numberSqrt(arg1) {
	if (notEmpty(arg1)) {
		return math.sqrt(arg1);
		math.number(math.sqrt(math.bignumber(arg1)));
	} else {
		return '-';
	}
}
//除
export function numberExcept(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.divide(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? '-' : price;
	} else {
		return '-';
	}
}
//乘
export function numberRide(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.multiply(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? '-' : price;
	} else {
		return '-';
	}
}
//加
export function numberAdd(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.add(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? '-' : price;
	} else {
		return '-';
	}
}
//减
export function numberSub(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.subtract(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? '-' : price;
	} else {
		return '-';
	}
}

export function checkNumberInput(value, callback) {
	let match = value.match(/^(0|([1-9]\d*))(\.\d{0,2})?$/);
	if (match) {
		callback(match[0]); // 如果匹配，返回匹配结果
	} else {
		if (value.startsWith('0') && value[1] !== '.') {
			callback(value.slice(1)); // 处理以0开头但后面不跟小数点的情况
		} else {
			callback(value.slice(0, -1)); // 不匹配，删除最后一个字符
		}
	}
}

export function checkListNumberInput(value) {
	let match = value.match(/^(0|([1-9]\d*))(\.\d{0,2})?$/);
	if (match) {
		return match[0]; // 如果匹配，返回匹配结果
	} else {
		if (value.startsWith('0') && value[1] !== '.') {
			return value.slice(1); // 处理以0开头但后面不跟小数点的情况
		} else {
			return value.slice(0, -1); // 不匹配，删除最后一个字符
		}
	}
}
export function format_thousand(number) {
	if (Empty(number)) return '-';
	let price = number * 1;
	if (!Number.isFinite(price)) return '-';
	let fixed2 = price.toFixed(2);
	return !(fixed2 + '').includes('.')
		? // 就是说1-3位后面一定要匹配3位
		  (fixed2 + '').replace(/\d{1,3}(?=(\d{3})+$)/g, match => {
				return match + ',';
		  })
		: (fixed2 + '').replace(/\d{1,3}(?=(\d{3})+(\.))/g, match => {
				return match + ',';
		  });
	// return new Intl.NumberFormat("en-us").format(fixed2);
}

export function checkEmptyString(value) {
	if (value == null || value == undefined || value == '') {
		return '/';
	} else {
		return value;
	}
}
//开方
export function toNumberSqrt(arg1) {
	if (notEmpty(arg1)) {
		return math.sqrt(arg1);
		math.number(math.sqrt(math.bignumber(arg1)));
	} else {
		return undefined;
	}
}
//除
export function toNumberExcept(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.divide(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? undefined : price;
	} else {
		return undefined;
	}
}
//乘
export function toNumberRide(arg1, arg2) {
	if (notEmpty(arg1) && notEmpty(arg2)) {
		let price = math.number(
			math.multiply(math.bignumber(arg1), math.bignumber(arg2)),
		);
		return isNaN(price) ? undefined : price;
	} else {
		return undefined;
	}
}

//加
export function toNumberAdd(arg1, arg2) {
	if (Empty(arg1) && Empty(arg2)) {
		return undefined;
	}
	if (notEmpty(arg1) || notEmpty(arg2)) {
		let price = math.number(
			math.add(math.bignumber(arg1 ?? 0), math.bignumber(arg2 ?? 0)),
		);
		return isNaN(price) ? undefined : price;
	} else {
		return undefined;
	}
}
//减
export function toNumberSub(arg1, arg2) {
	if (Empty(arg1) && Empty(arg2)) {
		return undefined;
	}
	if (notEmpty(arg1) || notEmpty(arg2)) {
		let price = math.number(
			math.subtract(math.bignumber(arg1 ?? 0), math.bignumber(arg2 ?? 0)),
		);
		return isNaN(price) ? undefined : price;
	} else {
		return undefined;
	}
}
// 数组对象遍历  值为空返回"-"
export function processArray(arr) {
	return arr.map(item => {
		for (let key in item) {
			if (item.hasOwnProperty(key)) {
				if (
					item[key] === null ||
					item[key] === undefined ||
					item[key] === ''
				) {
					item[key] = '--';
				}
			}
		}
		return item;
	});
}
export function getChain(row, prop, index) {
	if (
		Object.prototype.toString.call(prop) !== '[object String]' &&
		Object.prototype.toString.call(prop) !== '[object Array]'
	) {
		return undefined;
	}
	let data = [];
	if (typeof prop === 'string') {
		// data = prop.split('.');
		data = getChainKey(prop);
	}
	if (notEmpty(index)) {
		data = data.slice(0, index);
	}
	let result = data.reduce(function (prev, next) {
		return prev?.[next];
	}, row);
	if (notEmpty(index)) {
		if (index == -1) {
			return { data: result, spread: data.slice(index)[0] };
		} else {
			return { data: result, spread: data.slice(index) };
		}
	}
	return result;
}

export function getChainKey(str) {
	if (Empty(str)) {
		return [];
	}
	let regex = /\w+/g;
	let matches = str.match(regex);
	return matches;
}
export function setData(row, prop, data) {
	if (Empty(prop)) {
		return false;
	}
	let keys = getChainKey(prop);
	if (keys.length == 0) {
		return false;
	}
	let obj = row;
	keys.forEach((key, index) => {
		if (index !== keys.length - 1) {
			if (!obj.hasOwnProperty(key)) {
				Vue.set(obj, key, {});
			}
			obj = obj[key];
		} else {
			Vue.set(obj, key, data);
			return true;
		}
	});
	return false;
}
export function initData(row, prop, data) {
	if (Empty(prop)) {
		return false;
	}
	let keys = getChainKey(prop);
	if (keys.length == 0) {
		return false;
	}
	let obj = row;
	keys.forEach((key, index) => {
		if (index !== keys.length - 1) {
			if (!obj.hasOwnProperty(key)) {
				Vue.set(obj, key, {});
			}
			obj = obj[key];
		} else {
			if (!obj.hasOwnProperty(key)) {
				Vue.set(obj, key, undefined);
			}
			return true;
		}
	});
	return false;
}
export function encodeParams(query) {
	query ??= {};
	if (Object.prototype.toString.call(query) === '[object Object]') {
		let result = '';
		try {
			result = encodeURIComponent(JSON.stringify(query));
		} catch (error) {}
		return result;
	} else {
		throw new Error('参数 query 必须是 Object 类型');
	}
}
export function decodeParams(query) {
	if (Object.prototype.toString.call(query) === '[object String]') {
		let result = {};
		try {
			result = JSON.parse(decodeURIComponent(query));
		} catch (error) {}

		return result;
	} else {
		return {};
	}
}
